home *** CD-ROM | disk | FTP | other *** search
- #include <ctype.h>
- #include <stdio.h>
-
- #include "fudgit.h"
- #include "macro.h"
- #include "symbol.h"
- #include "code.h"
- #include "math.tab.h"
- #include "head.h"
-
- #define SQUOTE '\''
- #define DQUOTE '"'
- #define BACKSLASH
-
- extern int Ft_almost(char *, char *);
-
- #define COPY(pOinter) *cp++ = p[argno][j++] = *pOinter++;\
- if (j >= TOKENSIZE) {\
- fprintf(stderr, "Argument %d too long.\n", argno);\
- return(ERRR);\
- }
-
- #define CHECKMODE if (leavequotes == ERRR) {\
- leavequotes = (Ft_almost(p[0], "pm!ode") ||\
- Ft_almost(p[0], "cm!ode") ||\
- Ft_almost(p[0], "le!t") ||\
- Ft_maclook(p[0], ANALIAS) );\
- if (leavequotes) {\
- COPY(b);\
- break;\
- }\
- }\
-
- /* given a buffered line b, a string vector p, return the number of
- * arguments found and copied. expand local variables.
- * Returns: no of arg
- * NL for newline
- * ERRR for serious errors
- * VERRR for variable errors (for history purposes)
- */
-
- extern char Ft_Vformat[];
- extern char Ft_Comchar;
- extern char Ft_Home[];
- extern int Ft_iolevel(void);
- extern char *getenv(const char *);
- static char buffer[LINESIZE];
-
- int Ft_vgetargp(char *b, char **p, int type, char **add)
- {
- static char qtstype[] = "\"'";
- int j = 0;
- int argno = 0;
- int indquotes = 0;
- int insquotes = 0;
- int inpar = 0;
- int expansion = (type & EXPANSION);
- int quotes = (type & QUOTES);
- int parenth = (type & PARENTH);
- int leavequotes = (quotes == 0? YES: ERRR);
- char *cp = buffer;
- char *np;
-
- if (add)
- *add = cp;
-
- /* remove leading blanks */
- while (*b != '\0' && (*b == ' ' || *b == '\t' || *b == '\n'))
- b++;
- if (*b == '\0') return(NL);
-
- /* go along the string */
- while (*b != '\0' && argno < MAXTOKEN) {
- switch (*b) {
- #ifdef BACKSLASH
- case '\\': /* only recognize \$ in non fmodes */
- if (leavequotes == ERRR) {
- leavequotes = ( Ft_almost(p[0], "pm!ode") ||
- Ft_almost(p[0], "cm!ode") ||
- Ft_almost(p[0], "le!t") );
- }
- if (expansion && (!leavequotes || b[1] == '$')) {
- b++;
- }
- COPY(b);
- break;
- #endif
- case SQUOTE: /* take following as one string, + turn off exp */
- if (leavequotes == 1 || indquotes || inpar) {
- COPY(b);
- break;
- }
- CHECKMODE;
- b++;
- insquotes = !insquotes;
- break;
- case DQUOTE: /* take the following as one string */
- if (leavequotes == 1 || insquotes || inpar) {
- COPY(b);
- break;
- }
- CHECKMODE;
- b++;
- indquotes = !indquotes;
- break;
- case '$': /* try to expand a numeric variable */
- if (!insquotes && expansion &&
- (*(b+1) == '{' || *(b+1) == '[' ||
- *(b+1) == '_' || isalpha((int)*(b+1)))) {
- Symbol *sym;
- char name[TOKENSIZE];
- char format[TOKENSIZE];
- char *lp;
- int brace = 0;
- int bracket = 0;
-
- b++;
- if (*b == '{') {
- b++;
- brace = 1;
- }
- if (*b == '[') {
- b++;
- bracket = 1;
- np = format;
- while (*b && *b != ']') {
- *np++ = *b++;
- }
- *np = '\0';
- if (*b++ != ']') {
- fprintf(stderr, "Unmatched bracket: %s.\n", format);
- return(VERRR);
- }
- }
- np = name;
- /* name is alphanumeric */
- while (*b == '_' || isalnum((int)*b)) {
- *np++ = *b++;
- }
- *np = '\0';
- if (brace) {
- if (*b++ != '}') {
- fprintf(stderr, "Unmatched brace: %s.\n", name);
- return(VERRR);
- }
- }
- /* find the variable */
- if ((sym = Ft_lookup(name)) == 0) {
- fprintf(stderr,
- "Expansion error: %s: No such constant or variable.\n",
- name);
- return(VERRR);
- }
- /* The following crucially depends on the order in parse.y */
- if (sym->type >= VAR && sym->type <= BLTINCONST) {
- if (bracket)
- lp = format;
- else
- lp = Ft_Vformat;
- sprintf(name, lp, sym->u.val);
- lp = name;
- }
- else if (sym->type >= STRVAR && sym->type <= BLTINSTRCONST) {
- if (bracket) {
- sprintf(name, format, sym->u.str);
- lp = name;
- }
- else
- lp = sym->u.str;
- }
- else if (sym->type == UNDEFSTRVAR || sym->type == UNDEFVAR) {
- fprintf(stderr,
- "Expansion error: %s: Undefined variable.\n", name);
- return(VERRR);
- }
- else {
- fprintf(stderr,
- "Expansion error: %s: Not a printable variable.\n", name);
- return(VERRR);
- }
- while(*lp) { /* replace by value */
- COPY(lp);
- }
- }
- else { /* copy $ as is */
- COPY(b);
- }
- break;
- case '(':
- if (!parenth || (leavequotes == 1 && quotes == 1)
- || indquotes || insquotes) {
- COPY(b);
- break;
- }
- CHECKMODE;
- inpar++;
- if (inpar == 1 && j != 0) { /* start new argument on first '(' */
- p[argno][j] = '\0';
- argno++;
- j = 0;
- }
- COPY(b);
- break;
- case ')':
- if (!parenth || (leavequotes == 1 && quotes == 1)
- || indquotes || insquotes) {
- COPY(b);
- break;
- }
- CHECKMODE;
- inpar--;
- COPY(b);
- if (inpar == 0 && !isspace(*b)) { /* end argument on last ')' */
- p[argno][j] = '\0';
- argno++;
- j = 0;
- }
- break;
- case ' ': /* a space */
- case '\t':
- if (indquotes || inpar || insquotes) {
- p[argno][j] = ' ';
- j++;
- }
- else {
- p[argno][j] = '\0';
- argno++;
- j = 0;
- }
- *cp = ' '; cp++;
- /* remove interargument blanks */
- while (*b == ' ' || *b == '\t')
- b++;
- if (*b == '\n') {
- if (inpar) {
- fprintf(stderr, "Unmatched %c.\n",
- inpar>0? '(' : ')');
- return(VERRR);
- }
- if (indquotes || insquotes) {
- fprintf(stderr, "Unmatched %c.\n", qtstype[insquotes]);
- return(VERRR);
- }
- b++;
- if (*b != '\0') {
- fputs("Command contains more than one line.\n", stderr);
- return(ERRR);
- }
- *cp = '\n'; cp++; *cp = '\0';
- return(argno);
- }
- break;
- case '\n':
- if (inpar) {
- fprintf(stderr, "Unmatched %c.\n",
- inpar>0? '(' : ')');
- return(VERRR);
- }
- if (insquotes || indquotes) {
- fprintf(stderr, "Unmatched %c.\n", qtstype[insquotes]);
- return(VERRR);
- }
- *cp = '\n'; cp++;
- *cp = p[argno][j] = '\0';
- argno++; b++;
- if (*b != '\0') {
- fputs("Command contains more than one line.\n", stderr);
- return(ERRR);
- }
- return(argno);
- case '~':
- b++;
- np = Ft_Home;
- while (*np) { /* replace by variable */
- COPY(np);
- }
- break;
- default:
- /* ignore comment except when interactive */
- if (*b == Ft_Comchar && !indquotes && !insquotes &&
- !inpar && (Ft_iolevel() || !expansion)) {
- *cp = '\n'; cp++;
- *cp = p[argno][j] = '\0';
- if (j != 0) argno++;
- return(argno);
- } /* otherwise go through */
- COPY(b);
- break;
- }
- }
- fputs("Tokenizer: Line too long or not terminated.\n", stderr);
- return(ERRR);
- }
-
-